/**
 * Created with IntelliJ IDEA.
 * User: osereda
 * Date: 04.06.13
 */
package com.google.code.bankagregator.adapter.bank.sberrus.reader.deposit;

import com.google.code.bankagregator.adapter.exception.AdapterException;
import com.google.code.bankagregator.common.DetectCurrency;
import com.google.code.bankagregator.common.reader.DepositReader;
import com.google.code.bankagregator.entities.Bank;
import com.google.code.bankagregator.entities.Deposit;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.util.List;

abstract class AbstractDepositSber implements DepositReader {

    protected final String MIN_AMOUNT_HTML = "p:contains(Минимальная сумма)";
    protected final String MAX_AMOUNT_HTML = "p:contains(Максимальная сумма)";
    protected final String PRODUCT_TABLE_HTML = "div.text table tr";
    protected final int DAYS_PER_MONTH = 31;
    private final String BANK_TITLE = "ПАО «СБЕРБАНК РОССИИ»";
    private final String SITE_URL = "http://sberbank.ua/";
    private Bank bank;
    private String productURL;

    /**
     * @param url string URL of specified product page
     */
    public AbstractDepositSber(String url) {
        bank = new Bank();
        bank.setName(BANK_TITLE);
        bank.setUrl(SITE_URL);
        productURL = url;
    }

    /**
     * @return string URL of current product page
     */
    public String getDepositPageURL() {
        return productURL;
    }

    /**
     * @return Bank VO with data for current product
     */
    public Bank getBank() {
        return bank;
    }

    /**
     * Search for value with specified currency
     *
     * @param source   array of currency data
     * @param currency specified currency
     * @return numeric value or -1 if value with specified currency not found.
     */
    public int getValueByCurrency(String[] source, String currency) {
        for (String s : source) {
            if (s.contains(currency)) {
                return Integer.valueOf(s.replaceAll("\\D+", ""));
            }
        }
        return -1;
    }

    abstract public List<Deposit> getDeposits() throws AdapterException;

    /**
     * Read max and min deposit amount string into currency depended array.
     *
     * @param string line with come separated amount values with currency labels.
     * @return String[] with summ and currency code.
     */
    public String[] getAmount(String string, String divider) {
        DetectCurrency recodeDetectCurrency = new DetectCurrency();
        String line[] = string.split(divider);
        String c[] = line[1].split(",");
        String codeLine = "";
        for (String str : c) {
            String curr = recodeDetectCurrency.getCurrencyAbbreviation(str);
            if (curr == null) {
                continue;
            }
            codeLine = codeLine + str.replaceAll("\\D+", "") + curr + "@";
        }
        return codeLine.split("@");
    }

    /**
     * Reads data from table with rate depended from currency and period.
     *
     * @param elms HTML Jsoup.Elements with table.
     * @return table as 2D String array.
     */
    public String[][] getTableHorizontal(Elements elms) {
        DetectCurrency recodeDetectCurrency = new DetectCurrency();
        String s1 = "";
        for (Element elm : elms) {
            for (Element el : elm.getElementsByTag("th")) {
                if (el.attr("colspan").isEmpty()) {
                    s1 = s1 + el.tagName() + ":" + el.text() + "@";
                }
            }
            for (Element el : elm.getElementsByTag("td")) {
                s1 = s1 + el.tagName() + ":" + el.text() + "@";
            }
        }

        String[] data = s1.split("@");
        int x = 0;
        for (String s : data) {
            if ("th".equals(s.split(":")[0].toLowerCase())) {
                x++;
            }
        }

        int y = data.length / x;
        String[][] retVal = new String[y][x];
        int z = 0;
        for (String s : data) {
            String cell = s.split(":")[1].toLowerCase();
            String curr = recodeDetectCurrency.getCurrencyAbbreviation(cell);
            if (curr.isEmpty()) {
                retVal[z / x][z % x] = cell;
            } else {
                retVal[z / x][z % x] = curr;
            }
            z++;
        }
        return retVal;
    }

    /**
     * Reads data from table with rate depended from currency and period.
     *
     * @param elms HTML Jsoup.Elements with table.
     * @return table as 2D String array.
     */
    public String[][] getTableVertical(Elements elms) {
        DetectCurrency recodeDetectCurrency = new DetectCurrency();
        String s1 = "";
        for (Element elm : elms) {
            for (Element el : elm.getElementsByTag("th")) {
                if (el.attr("colspan").isEmpty()) {
                    s1 = s1 + el.tagName() + ":" + el.text() + "@";
                }
            }
            for (Element el : elm.getElementsByTag("td")) {
                s1 = s1 + el.tagName() + ":" + el.text() + "@";
            }
        }

        String[] data = s1.split("@");
        int x = 0;
        for (String s : data) {
            if ("th".equals(s.split(":")[0].toLowerCase())) {
                x++;
            }
        }
        int y = data.length / x;
        String[][] retVal = new String[x][y];
        int z = 0;
        for (String s : data) {
            String cell = s.split(":")[1].toLowerCase();
            String curr = recodeDetectCurrency.getCurrencyAbbreviation(cell);
            if (curr.isEmpty()) {
                retVal[z % x][z / x] = cell;
            } else {
                retVal[z % x][z / x] = curr;
            }
            z++;
        }
        return retVal;
    }
}
